﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.RazorEditorParser
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using Microsoft.Internal.Web.Utils;
using System.Diagnostics;
using System.Globalization;
using System.Web.Razor.Editor;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Text;

namespace System.Web.Razor
{
  /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Parser used by editors to avoid reparsing the entire document on each text change.</summary>
  public class RazorEditorParser : IDisposable
  {
    private Span _lastChangeOwner;
    private Span _lastAutoCompleteSpan;
    private BackgroundParser _parser;
    private Block _currentParseTree;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Constructs the editor parser.</summary>
    /// <param name="host">The <see cref="T:System.Web.Razor.RazorEngineHost" /> which defines the environment in which the generated code will live.</param>
    /// <param name="sourceFileName">The physical path to use in line pragmas.</param>
    public RazorEditorParser(RazorEngineHost host, string sourceFileName)
    {
      if (host == null)
        throw new ArgumentNullException(nameof (host));
      if (string.IsNullOrEmpty(sourceFileName))
        throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, nameof (sourceFileName));
      this.Host = host;
      this.FileName = sourceFileName;
      this._parser = new BackgroundParser(host, sourceFileName);
      this._parser.ResultsReady += (EventHandler<DocumentParseCompleteEventArgs>) ((sender, args) => this.OnDocumentParseComplete(args));
      this._parser.Start();
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Event fired when a full reparse of the document completes.</summary>
    public event EventHandler<DocumentParseCompleteEventArgs> DocumentParseComplete;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the host for the parse.</summary>
    /// <returns>The host for the parse.</returns>
    public RazorEngineHost Host { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets the filename of the document to parse.</summary>
    /// <returns>The filename of the document to parse.</returns>
    public string FileName { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets or sets a value indicating whether the last result of the parse was provisionally accepted for next partial parse.</summary>
    /// <returns>true if the last result of the parse was provisionally accepted for next partial parse; otherwise, false.</returns>
    public bool LastResultProvisional { get; private set; }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Gets the current parse tree.</summary>
    /// <returns>The current parse tree.</returns>
    public Block CurrentParseTree => this._currentParseTree;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Retrieves the auto complete string.</summary>
    /// <returns>The auto complete string.</returns>
    public virtual string GetAutoCompleteString() => this._lastAutoCompleteSpan != null && this._lastAutoCompleteSpan.EditHandler is AutoCompleteEditHandler editHandler ? editHandler.AutoCompleteString : (string) null;

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Determines if a change will cause a structural change to the document and if not, applies it to the existing tree. If a structural change would occur, automatically starts a reparse.</summary>
    /// <returns>A <see cref="T:System.Web.Razor.PartialParseResult" /> value indicating the result of the incremental parse.</returns>
    /// <param name="change">The change to apply to the parse tree.</param>
    public virtual PartialParseResult CheckForStructureChanges(TextChange change)
    {
      if (change.NewBuffer == null)
        throw new ArgumentException(string.Format((IFormatProvider) CultureInfo.CurrentUICulture, RazorResources.Structure_Member_CannotBeNull, (object) "Buffer", (object) "TextChange"), nameof (change));
      PartialParseResult partialParseResult = PartialParseResult.Rejected;
      string empty = string.Empty;
      using (this._parser.SynchronizeMainThreadState())
      {
        change.ToString();
        if (this.CurrentParseTree != null)
        {
          if (this._parser.IsIdle)
            partialParseResult = this.TryPartialParse(change);
        }
      }
      if (partialParseResult.HasFlag((Enum) PartialParseResult.Rejected))
        this._parser.QueueChange(change);
      this.LastResultProvisional = partialParseResult.HasFlag((Enum) PartialParseResult.Provisional);
      return partialParseResult;
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Releases all resources used by the current instance of the <see cref="T:System.Web.Razor.RazorEditorParser" />.</summary>
    public void Dispose()
    {
      this.Dispose(true);
      GC.SuppressFinalize((object) this);
    }

    /// <summary>This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.Releases the unmanaged resources used by the <see cref="T:System.Web.Razor.RazorEditorParser" /> class and optionally releases the managed resources.</summary>
    /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
    protected virtual void Dispose(bool disposing)
    {
      if (!disposing)
        return;
      this._parser.Dispose();
    }

    private PartialParseResult TryPartialParse(TextChange change)
    {
      PartialParseResult partialParseResult = PartialParseResult.Rejected;
      if (this._lastChangeOwner != null && this._lastChangeOwner.EditHandler.OwnsChange(this._lastChangeOwner, change))
      {
        EditResult editResult = this._lastChangeOwner.EditHandler.ApplyChange(this._lastChangeOwner, change);
        PartialParseResult result = editResult.Result;
        if (!editResult.Result.HasFlag((Enum) PartialParseResult.Rejected))
          this._lastChangeOwner.ReplaceWith(editResult.EditedSpan);
        return result;
      }
      this._lastChangeOwner = this.CurrentParseTree.LocateOwner(change);
      if (this.LastResultProvisional)
        partialParseResult = PartialParseResult.Rejected;
      else if (this._lastChangeOwner != null)
      {
        EditResult editResult = this._lastChangeOwner.EditHandler.ApplyChange(this._lastChangeOwner, change);
        partialParseResult = editResult.Result;
        if (!editResult.Result.HasFlag((Enum) PartialParseResult.Rejected))
          this._lastChangeOwner.ReplaceWith(editResult.EditedSpan);
        this._lastAutoCompleteSpan = !partialParseResult.HasFlag((Enum) PartialParseResult.AutoCompleteBlock) ? (Span) null : this._lastChangeOwner;
      }
      return partialParseResult;
    }

    private void OnDocumentParseComplete(DocumentParseCompleteEventArgs args)
    {
      using (this._parser.SynchronizeMainThreadState())
      {
        this._currentParseTree = args.GeneratorResults.Document;
        this._lastChangeOwner = (Span) null;
      }
      EventHandler<DocumentParseCompleteEventArgs> documentParseComplete = this.DocumentParseComplete;
      if (documentParseComplete == null)
        return;
      try
      {
        documentParseComplete((object) this, args);
      }
      catch (Exception ex)
      {
      }
    }

    [Conditional("DEBUG")]
    private static void VerifyFlagsAreValid(PartialParseResult result)
    {
    }
  }
}
